#include "myhead.h"

/*
	四个线程分别代表五个不同的售票窗口
*/
int allnum=15; //G112次总的票数
int curnum=0; //当前票的数量
int synum; //统计剩余票的数量

//定义互斥锁
pthread_mutex_t mymutex;

//定义一个条件变量
pthread_cond_t mycond;

void *win1(void *arg)
{
	while(1)
	{
		pthread_mutex_lock(&mymutex);
		
		while(curnum<=0)  //之前写if(curnum<=0)单次判断 //票卖完了
		{
			//阻塞当前窗口(线程)
			printf("窗口1阻塞在wait！\n");
			pthread_cond_wait(&mycond,&mymutex);
		}
		curnum--;  
		printf("窗口1卖出一张票，还剩下%d张票!\n",curnum);
		sleep(1);
		pthread_mutex_unlock(&mymutex);
		usleep(100);
	}
}
void *win2(void *arg)
{
	while(1)
	{
		pthread_mutex_lock(&mymutex);
		while(curnum<=0) //票卖完了
		{
			//阻塞当前窗口(线程)
			printf("窗口2阻塞在wait！\n");
			pthread_cond_wait(&mycond,&mymutex); //先解锁，然后阻塞当前线程
		}
		curnum--; 
		printf("窗口2卖出一张票，还剩下%d张票!\n",curnum);
		sleep(1);
		pthread_mutex_unlock(&mymutex);
		usleep(100);
	}
}
void *win3(void *arg)
{
	while(1)
	{
		pthread_mutex_lock(&mymutex);
		while(curnum<=0) //票卖完了
		{
			//阻塞当前窗口(线程)
			printf("窗口3阻塞在wait！\n");
			pthread_cond_wait(&mycond,&mymutex);
		}
		curnum--;
		printf("窗口3卖出一张票，还剩下%d张票!\n",curnum);
		sleep(1);
		pthread_mutex_unlock(&mymutex);
		usleep(100);
	}
}

void *win4(void *arg)
{
	while(1)
	{
		pthread_mutex_lock(&mymutex);
		while(curnum<=0) //票卖完了
		{
			//阻塞当前窗口(线程)
			printf("窗口4阻塞在wait！\n");
			pthread_cond_wait(&mycond,&mymutex);
		}
		curnum--;
		printf("窗口4卖出一张票，还剩下%d张票!\n",curnum);
		sleep(1);
		pthread_mutex_unlock(&mymutex);
		usleep(100);
	}
}
int main()
{
	synum=allnum-curnum;
	//初始化锁
	pthread_mutex_init(&mymutex,NULL);
	
	//初始化条件变量
	pthread_cond_init(&mycond,NULL);
	pthread_t id1,id2,id3,id4;
	pthread_create(&id1,NULL,win1,NULL);
	pthread_create(&id2,NULL,win2,NULL);
	pthread_create(&id3,NULL,win3,NULL);
	pthread_create(&id4,NULL,win4,NULL);
	
	//主函数当成是铁道部，负责放票出来
	while(1)
	{
		if(curnum<=0)
		{
			printf("领导，G112次列车当前票已经卖完了，还剩下%d张票，请求放票出来!\n",synum);
			scanf("%d",&curnum);
			synum=synum-curnum;
			//唤醒条件变量
			//pthread_cond_signal(&mycond); //唤醒四个线程中的某一个
			pthread_cond_broadcast(&mycond);
			if(synum<=0&&curnum<=0)
			{
				pthread_cancel(id1);
				pthread_cancel(id2);
				pthread_cancel(id3);
				pthread_cancel(id4);
					break;
			}
		}
		
	}
	
	pthread_join(id1,NULL);
	pthread_join(id2,NULL);
	pthread_join(id3,NULL);
	pthread_join(id4,NULL);
}